package com.kun.companion.core.ui.alert;

import cn.hutool.core.util.StrUtil;
import com.kun.companion.core.exception.Assert;
import com.kun.companion.core.util.ImageLoader;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.DialogPane;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Region;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Window;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 抽象对话框基类，封装通用对话框行为和布局模板
 * <p>采用模板方法模式，子类需实现中心区域布局，可扩展顶部/底部区域</p>
 *
 * @param <T> 对话框返回值类型，需通过{@link #convertResult(ButtonType)}实现类型转换
 * @author gzc
 */
public abstract class AbstractDialog<T> extends Dialog<ButtonType> {
    private static final Logger log = LoggerFactory.getLogger(AbstractDialog.class);
    public static final int PREF_WIDTH = Integer.MAX_VALUE;
    public static final int PREF_HEIGHT = Integer.MAX_VALUE;

    /**
     * 对话框所属父窗口
     */
    protected final Window owner;

    /**
     * 根布局容器，采用BorderPane实现三区域布局
     */
    protected BorderPane root;

    /**
     * 全参数构造器
     *
     * @param title    对话框标题（支持多语言键）
     * @param iconPath 图标资源路径（格式：/package/file.png）
     * @param owner    父窗口，为null时关联主舞台
     * @param modality 模态类型，建议使用{@link Modality#APPLICATION_MODAL}
     */
    protected AbstractDialog(String title, String iconPath,
                             Window owner, Modality modality) {
        this.owner = owner;
        initBasicConfig(title, iconPath, modality);
        initDialogPane();
    }

    /**
     * 初始化基础配置
     *
     * @param title    对话框标题
     * @param iconPath 图标路径（空值时跳过设置）
     * @param modality 窗口模态类型
     * @throws IllegalArgumentException 初始化失败时抛出业务异常
     */
    private void initBasicConfig(String title, String iconPath, Modality modality) {
        try {
            setTitle(title);
            initModality(modality);
            initOwner(owner != null ? owner : Stage.getWindows().stream()
                    .filter(Window::isShowing)
                    .findFirst().orElse(null));
            setDialogIcon(iconPath);
        } catch (Exception e) {
            Assert.throwBizException(e, "对话框初始化失败: {}", e.getMessage());
        }
    }

    /**
     * 初始化对话框面板结构
     * <p>默认添加取消按钮，建立三区域布局容器</p>
     */
    private void initDialogPane() {
        DialogPane pane = getDialogPane();
        pane.getButtonTypes().add(ButtonType.CANCEL);
        root = new BorderPane();
        // 禁用默认header
        setHeaderText(null);

        // 构建布局区域
        setTop(createTop());
        setCenter(createCenter());
        setBottom(createBottom());

        pane.setContent(root);
        // 设置默认宽度
//        pane.setPrefWidth(PREF_WIDTH);
//        pane.setPrefHeight(PREF_HEIGHT);
    }

    /**
     * 设置顶部区域节点
     *
     * @param topNode 自定义区域组件，需继承Region
     */
    public void setTop(Region topNode) {
        root.setTop(topNode);
    }

    /**
     * 设置中心区域节点（核心内容区域）
     *
     * @param centerNode 自定义区域组件，需继承Region
     */
    public void setCenter(Region centerNode) {
        root.setCenter(centerNode);
    }

    /**
     * 设置底部区域节点（通常放置操作按钮）
     *
     * @param bottomNode 自定义区域组件，需继承Region
     */
    public void setBottom(Region bottomNode) {
        root.setBottom(bottomNode);
    }

    /**
     * 创建顶部区域（默认空实现）
     *
     * @return 可为null表示不显示顶部
     */
    protected Region createTop() {
        return null;
    }

    /**
     * 创建中心区域（抽象方法必须实现）
     */
    protected abstract Region createCenter();

    /**
     * 创建底部区域（默认空实现）
     */
    protected Region createBottom() {
        return null;
    }

    /**
     * 加载并设置对话框图标
     *
     * @param iconPath 图标资源路径（需确保资源可访问）
     */
    private void setDialogIcon(String iconPath) {
        if (StrUtil.isBlank(iconPath)) {
            log.debug("未配置对话框图标");
            return;
        }

        Image iconImage = ImageLoader.load(iconPath);
        if (iconImage == null) {
            log.error("图标资源加载失败: {}", iconPath);
            return;
        }

        Stage stage = (Stage) getDialogPane().getScene().getWindow();
        stage.getIcons().add(iconImage);
    }

    /**
     * 确认按钮点击事件处理（可被子类重写）
     */
    protected void handleConfirm() {
        // 默认空实现
    }

    /**
     * 取消按钮点击事件处理（可被子类重写）
     */
    protected void handleCancel() {
        // 默认空实现
    }

    /**
     * 将按钮类型转换为业务结果对象
     *
     * @param buttonType 用户点击的按钮类型
     * @return 业务逻辑需要的返回值，默认返回null
     */
    protected T convertResult(ButtonType buttonType) {
        return null;
    }

    /**
     * 显示对话框并等待用户响应
     *
     * @return 业务处理结果，需通过convertResult实现类型转换
     */
    public T showAndWaitResult() {
        ButtonType buttonType = showAndWait().orElse(ButtonType.CANCEL);
        if (buttonType == ButtonType.OK) {
            handleConfirm();
        } else {
            handleCancel();
        }
        close(); // 显式关闭释放资源
        return convertResult(buttonType);
    }
}